package com.dlc.felear.xiaoensale.factory;


import android.util.Log;

import com.dlc.felear.xiaoensale.utils.HexUtil;
import com.dlc.felear.xiaoensale.utils.SendJbCmdUtil;

/**
 * 指令工厂- 拼接指令
 * Created by felear on 2018/8/6.
 */

public class CmdSfList {

    private static final String TAG = "CmdSfList";


    /**
     * 查询报警信息
     *
     * @param add
     * @return
     */
    public static byte[] queryfWarn(int add) {
//        01 03 36 88 00 01 0B A8
        byte[] sendData = new byte[8];
        //帧头
        sendData[0] = (byte) add;
        //功能码
        sendData[1] = (byte) 0x03;
        //寄存器地址
        sendData[2] = (byte) 0x36;
        sendData[3] = (byte) 0x88;
        sendData[4] = (byte) 0x00;
        sendData[5] = (byte) 0x01;
        //crc检验
        checkCRC16(sendData);
        return sendData;
    }

    /**
     * 复位报警
     *
     * @param add
     * @return
     */
    public static byte[] sfClearWarn(int add) {
        //01 06 36 07 00 04 36 40
        byte[] sendData = new byte[8];
        //帧头
        sendData[0] = (byte) add;
        //功能码
        sendData[1] = (byte) 0x06;
        //寄存器地址
        sendData[2] = (byte) 0x36;
        sendData[3] = (byte) 0x07;
        sendData[4] = (byte) 0x00;
        sendData[5] = (byte) 0x04;
        //crc检验
        checkCRC16(sendData);
        return sendData;
    }

    /**
     * 写寄存器信息
     *
     * @param add
     * @return
     */
    public static byte[] sfWriteRegister(int add, int regAdd, int value) {
        //01 06 08 01 00 02 5B AB  01 06 08 01 00 02 5B AB
        byte[] sendData = new byte[8];
        //帧头
        sendData[0] = (byte) add;
        //功能码
        sendData[1] = (byte) 0x06;
        //寄存器地址
        byte[] temp1 = HexUtil.intTwoBytes(regAdd);
        sendData[2] = temp1[1];
        sendData[3] = temp1[0];
        byte[] temp2 = HexUtil.intTwoBytes(value);
        sendData[4] = temp2[1];
        sendData[5] = temp2[0];

        //crc检验
        checkCRC16(sendData);
        return sendData;
    }
    /**
     * 写多个寄存器信息
     *
     * @param add
     * @return
     */
    public static byte[] sfWrite32Register(int add, int regAdd, int value) {
//        设置P08.06为20000
//        01 10 08 06 00 02 04 4E 20 00 00 02 A7
        byte[] sendData = new byte[13];
        //帧头
        sendData[0] = (byte) add;
        //功能码
        sendData[1] = (byte) 0x10;
        //寄存器地址
        byte[] temp1 = HexUtil.intTwoBytes(regAdd);
        sendData[2] = temp1[1];
        sendData[3] = temp1[0];
        //寄存器个数
        byte[] temp2 = HexUtil.intTwoBytes(2);
        sendData[4] = temp2[1];
        sendData[5] = temp2[0];
        //数据长度，即4个字节
        sendData[6] = 0x04;
        byte[] temp3 = HexUtil.intToBytes(value);
        sendData[7] = temp3[3];
        sendData[8] = temp3[2];
        sendData[9] = temp3[1];
        sendData[10] = temp3[0];
        //crc检验
        checkCRC16(sendData);
        Log.e(TAG,"sfWrite32Register="+HexUtil.bytes2HexString(temp3));
        return sendData;
    }

    /**
     * 写寄存器信息
     *
     * @param add    总线地址
     * @param regAdd 寄存器地址
     * @param value  连续寄存器个数
     * @return
     */
    public static byte[] sfReadRegister(int add, int regAdd, int value) {
        //01 06 08 01 00 02 5B AB  01 06 08 01 00 02 5B AB
        byte[] sendData = new byte[8];
        //帧头
        sendData[0] = (byte) add;
        //功能码
        sendData[1] = (byte) 0x03;
        //寄存器地址
        byte[] temp1 = HexUtil.intTwoBytes(regAdd);
        sendData[2] = temp1[1];
        sendData[3] = temp1[0];
        byte[] temp2 = HexUtil.intTwoBytes(value);
        sendData[4] = temp2[1];
        sendData[5] = temp2[0];

        //crc检验
        checkCRC16(sendData);
        return sendData;
    }
    public static byte[] sfReadCurrentP(int add) {
        byte[] sendData = new byte[8];
        //帧头
        sendData[0] = (byte) add;
        //功能码
        sendData[1] = (byte) 0x03;
        //寄存器地址
        sendData[2] = (byte) 0x15;
        sendData[3] = (byte) 0x07;
        sendData[4] = (byte) 0x00;
        sendData[5] = (byte) 0x02;
        //crc检验
        checkCRC16(sendData);
        return sendData;
    }


    /**
     * 点动反转
     *
     * @param add
     * @return
     */
    public static byte[] sfRunZz(int add) {
        //01 06 36 08 00 04 06 43
        byte[] sendData = new byte[8];
        sendData[0] = (byte) add;
        sendData[1] = (byte) 0x06;
        sendData[2] = (byte) 0x36;
        sendData[3] = (byte) 0x08;
        sendData[4] = (byte) 0x00;
        sendData[5] = (byte) 0x04;
        //crc检验
        checkCRC16(sendData);
        return sendData;
    }

    /**
     * 点动正转
     *
     * @param add
     * @return
     */
    public static byte[] sfRunFz(int add) {
        //01 06 36 08 00 04 08 43
        byte[] sendData = new byte[8];
        sendData[0] = (byte) add;
        sendData[1] = (byte) 0x06;
        sendData[2] = (byte) 0x36;
        sendData[3] = (byte) 0x08;
        sendData[4] = (byte) 0x00;
        sendData[5] = (byte) 0x08;
        //crc检验
        checkCRC16(sendData);
        return sendData;
    }
    /**
     * 执行
     *
     * @param add
     * @return
     */
    public static byte[] sfStartRun(int add) {
        //01 06 36 08 02 00 06 E0
        byte[] sendData = new byte[8];
        sendData[0] = (byte) add;
        sendData[1] = (byte) 0x06;
        sendData[2] = (byte) 0x36;
        sendData[3] = (byte) 0x08;
        sendData[4] = (byte) 0x02;
        sendData[5] = (byte) 0x00;
        //crc检验
        checkCRC16(sendData);
        return sendData;
    }
    /**
     * 执行
     *
     * @param add
     * @return
     */
    public static byte[] sfStopRun(int add) {
        //01 06 36 08 02 00 06 E0
        byte[] sendData = new byte[8];
        sendData[0] = (byte) add;
        sendData[1] = (byte) 0x06;
        sendData[2] = (byte) 0x36;
        sendData[3] = (byte) 0x08;
        sendData[4] = (byte) 0x00;
        sendData[5] = (byte) 0x00;
        //crc检验
        checkCRC16(sendData);
        return sendData;
    }

    /**
     * 设置当前点为原点
     *
     * @param add
     * @return
     */
    public static byte[] sfSetYd(int add) {
        //01 06 14 0C 00 01 8D F9
        byte[] sendData = new byte[8];
        sendData[0] = (byte) add;
        sendData[1] = (byte) 0x06;
        sendData[2] = (byte) 0x14;
        sendData[3] = (byte) 0x0C;
        sendData[4] = (byte) 0x00;
        sendData[5] = (byte) 0x01;
        //crc检验
        checkCRC16(sendData);
        return sendData;
    }
    /**
     * 运行到某一段
     *
     * @param add
     * @return
     */
    public static byte[] sfRunPosition(int add,int num) {
        //01 06 14 0B 00 01
        byte[] sendData = new byte[8];
        sendData[0] = (byte) add;
        sendData[1] = (byte) 0x06;
        sendData[2] = (byte) 0x14;
        sendData[3] = (byte) 0x0B;
        sendData[4] = (byte) 0x00;
        sendData[5] = (byte) num;
        //crc检验
        checkCRC16(sendData);
        return sendData;
    }


    //校验码CRC16
    private static void checkCRC16(byte[] bytes) {
        int crc = 0xffff;
        for (int i = 0; i < bytes.length - 2; i++) {
            crc ^= (bytes[i] & 0xff);
            for (int j = 0; j < 8; j++) {
                if ((crc & 1) == 1) {
                    crc >>= 1;
                    crc ^= 0xa001;
                } else {
                    crc >>= 1;
                }
            }
        }
        // 取高低位
        bytes[bytes.length - 1] = (byte) (crc >> 8);
        bytes[bytes.length - 2] = (byte) crc;
    }


    /**
     * 16位的crc校验
     *
     * @param bytes
     * @return
     */
    public static boolean checkDataComplete(byte[] bytes) {

        int crc = 0xffff;
        for (int i = 0; i < bytes.length - 2; i++) {
            crc ^= (bytes[i] & 0xff);
            for (int j = 0; j < 8; j++) {
                if ((crc & 1) == 1) {
                    crc >>= 1;
                    crc ^= 0xa001;
                } else {
                    crc >>= 1;
                }
            }

        }
        if (bytes[bytes.length - 1] == (byte) (crc >> 8) &&
                bytes[bytes.length - 2] == (byte) crc) {
            return true;
        }
        return false;
    }


}
